#include "gd32f3x0.h"
#include <stdio.h>
#include <string.h>
#include "gd32f310k_start.h"
#include "gd32f3x0_it.h"
#include "systick.h"
#include "bsp_usart.h"
#include "bsp_led.h"

typedef enum {
	e_min=-1,
	e_init=0,
	e_at_ok,
	e_wifi_ok,
	e_sock_ok,
	e_connect_ok,
	e_max
} e_at_state;

uint8_t sat(char *cmd, char *expectRsp);
uint16_t wait_atrsp(char *rsp);

void init(void)
{
	rcu_periph_clock_enable(RCU_DMA);
	systick_config();
	led_init();

	/* initilize the com */
	usart0_gpio_config();
	usart0_config();
	usart1_gpio_config();
	usart1_config();
	printf("[%s] OK\r\n",__func__);
}

int main(void)
{
		e_at_state at_state = e_init;
    /* enable DMA clock */
    
		init();
		led_flash(5);
    while(1) {
			switch (at_state)
			{
				case e_init:
					sat("ATE0\r\n", "OK");
				
					if(!sat("AT\r\n", "OK")){
						led_on();
						at_state = e_at_ok;
					}
					else{
						delay_1ms(100);
						led_off();
					}
				break;
				case e_at_ok:
					if(!sat("AT+CWJAP=\"testssid\",\"12345678\"\r\n", "WIFI GOT IP"))
					{
						at_state = e_wifi_ok;
					}
					else{
						delay_1ms(100);
					}
				break;
				case e_wifi_ok:
					if(!sat("AT+CIFSR\r\n", "CIFSR:STAIP"))
					{
						at_state = e_sock_ok;
					}
					else
					{
						delay_1ms(100);
					}
					at_state = e_sock_ok;
				break;
				case e_sock_ok:
					//close socket
					sat("AT+CIPCLOSE\r\n", "OK");
					//start a new socket
					if(!sat("AT+CIPSTART=\"TCP\",\"192.168.1.36\",1314\r\n", "CONNECT"))
					{
						//sat("AT+CIPSEND=10","OK");
						at_state = e_connect_ok;
					}
					else
					{
						delay_1ms(100);
					}
				break;
				case e_connect_ok:
				{
					char at_resp[128] = {0};
					wait_atrsp(at_resp);
					
					if(strstr(at_resp,"on")){
						printf("light on\n");
						led_on();
					}
					else if(strstr(at_resp,"off")){
						printf("light off\n");
						led_off();
					}
					else if(strstr(at_resp, "blink"))
					{
						printf("buling buling\n");
						led_flash(10);
					}
					else
					{
						printf("other cmd got:[%s]\r\n", at_resp);
					}
				}
				break;
				default:
					printf("Get into other:%d\n",at_state);
				break;
			}
			//delay_1ms(100);
    }
}

uint8_t sat(char *cmd, char *rsp)
{
	char rsp_buff[BUFFER_SIZE] = {0};
	printf("at req:[%s]\n",cmd);
	usart_send_data((uint8_t *)cmd,strlen(cmd));
	usart_recv_data((uint8_t *)rsp_buff,BUFFER_SIZE);
	printf("at resp:[%s]\n", rsp_buff);
	
	if(strstr(rsp_buff,rsp))
	{
		return 0;
	}
	else
	{
		return 1;
	}
}

uint16_t wait_atrsp(char *rsp)
{
	uint16_t ret = 0;
	uint8_t recv_len = 0;
	if(rsp == NULL)
	{
		return ret;
	}
	//recv_len = usart_dma_recv(USART0, (uint8_t *)rsp, 64);
	recv_len = usart_recv_data((uint8_t *)rsp, 64);
	
	ret = recv_len;
	return ret;
}
/* retarget the C library printf function to the USART */
int fputc(int ch, FILE *f)
{
    usart_data_transmit(USART1, (uint8_t) ch);
    while(RESET == usart_flag_get(USART1, USART_FLAG_TBE));
    return ch;
}

